﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyServer.Common
{
    /// <summary>
    /// 表示数据打包器
    /// </summary>
    public static class DataPacker
    {

        #region========私有变量========

        /// <summary>
        /// 打包线程锁
        /// </summary>
        private static object packlock = new object();
        /// <summary>
        /// 解包线程锁
        /// </summary>
        private static object unpacklock = new object();

        #endregion

        #region========公有函数========

        /// <summary>
        /// 将数据打包成数据包列表
        /// </summary>
        /// <param name="Data">要打包的数据</param>
        /// <param name="PackageSize">单个数据包的大小</param>
        /// <param name="pkgName">数据包名称</param>
        /// <returns>打包完毕的数据包列表</returns>
        public static DataPackageCollection PackData(byte[] Data, uint PackageSize, string pkgName)
        {
            lock (packlock)
            {
                return PackData(Data, 0, Data.Length, PackageSize, pkgName);
            }
        }

        /// <summary>
        /// 将数据打包成数据包列表
        /// </summary>
        /// <param name="Data">要打包的数据</param>
        /// <param name="Offset">数据的起始偏移</param>
        /// <param name="Size">数据的大小</param>
        /// <param name="PackageSize">单个数据包的大小</param>
        /// <param name="pkgName">数据包名称</param>
        /// <returns>打包完毕的数据包列表</returns>
        public static DataPackageCollection PackData(byte[] Data, long Offset, long Size, uint PackageSize, string pkgName)
        {
            lock (packlock)
            {
                DataPackageCollection col = new DataPackageCollection(pkgName, PackageCollectionType.ForSend);
                long i = 0;
                long l = 0;
                long pkgSize = PackageSize;
                while (l <= Size)
                {
                    DataPackage pkg;
                    if (l + PackageSize > Size)
                    {
                        pkg = new DataPackage(Data, Offset + l, Size - l, i, pkgName);
                    }
                    else
                    {
                        pkg = new DataPackage(Data, Offset + l, PackageSize, i, pkgName);
                    }
                    col.Add(pkg);
                    i++;
                    l += PackageSize;
                }
                col.PackageName = pkgName;
                return col;
            }
        }

        /// <summary>
        /// 将指定数据打包成单数据包式数据包列表
        /// </summary>
        /// <param name="Data">要打包的数据</param>
        /// <param name="pkgName">数据包列表名称</param>
        /// <returns>打包完毕的数据包列表</returns>
        public static DataPackageCollection PackData(byte[] Data,string pkgName)
        {
            return new DataPackageCollection(pkgName, PackageCollectionType.ForSend, Data);
        }

        /// <summary>
        /// 将数据包列表解包成数据
        /// </summary>
        /// <param name="col">数据包列表</param>
        /// <returns>解包后的数据</returns>
        public static byte[] UnPackData(DataPackageCollection col)
        {
            lock (unpacklock)
            {
                if (col.DataCount == 0)
                {
                    List<byte> lb = new List<byte>();
                    col.QuickSort(0, col.Count - 1);
                    foreach (DataPackage pkg in col)
                    {
                        lb.AddRange(pkg.GetData());
                    }
                    return lb.ToArray();
                }
                else
                {
                    return col.Datas;
                }
            }
        }

        #endregion

    }
}
